#include "docentity.h"
#include "treedoc.h"
#include "confirmdialog.h"

DocEntity::Operations::Operations(){}
void DocEntity::Operations::addOperation(const int &Index, QAction *action)
{
    Operation operation;
    operation.enabled=false;
    operation.action=action;
    m_operations[Index]=operation;
    m_operations.keys();
}
void DocEntity::Operations::turnOff()
{
    foreach(int key,m_operations.keys()) setEnabled(key,false);
}
void DocEntity::Operations::setEnabled(const int &Index, const bool &enabled)
{
    m_operations[Index].enabled=enabled;
}
QAction* DocEntity::Operations::operation(const int &Index)
{
    return m_operations.value(Index).action;
}
bool DocEntity::Operations::isEnabled(const int &Index) const
{
    return m_operations.value(Index).enabled;
}
QList<QAction*> DocEntity::Operations::list(OperationType operationType) const
{
    QList<QAction*> actions;
    foreach(Operation op, m_operations.values())
    {
       if(operationType==DocEntity::Operations::All) actions.append(op.action);
       else
       {
           if(operationType==DocEntity::Operations::Enabled)
           {
               if(op.enabled) actions.append(op.action);
           }
           else
               if(!op.enabled) actions.append(op.action);
       }
    }
    return actions;
}

DocEntity::DocEntity(QTreeWidgetItem *parent) :
    QTreeWidgetItem(parent), m_level(0), m_id(0), m_num(0)
{
    if(parent!=0) m_level=dynamic_cast<DocEntity*>(parent)->level()+1;
    connect(this,SIGNAL(childWakedUp(DocEntity*)), dynamic_cast<TreeDoc*>(treeWidget()),SIGNAL(childWakeUp(DocEntity*)));
    connect(this,SIGNAL(removeItem(DocEntity*)),dynamic_cast<TreeDoc*>(treeWidget()),SLOT(removeItem(DocEntity*)));
    connect(this,SIGNAL(stateMessage(QString,int)),dynamic_cast<TreeDoc*>(treeWidget()),SIGNAL(state_message(QString,int)));
    connect(this,SIGNAL(newItem(DocEntity*)), dynamic_cast<TreeDoc*>(treeWidget()),SLOT(turnOnHighlight(DocEntity*)));
    connect(this,SIGNAL(changed()),this,SLOT(onChanged()));
    connect(this,SIGNAL(wasChanged(DocEntity*)),dynamic_cast<TreeDoc*>(treeWidget()),SLOT(onChangedItem(DocEntity*)));
    connect(this,SIGNAL(wasSaved(DocEntity*)),dynamic_cast<TreeDoc*>(treeWidget()),SLOT(onSavedItem(DocEntity*)));
    connect(this,SIGNAL(wasRefresh()),dynamic_cast<TreeDoc*>(treeWidget()),SIGNAL(wasRefreshItem()));
    setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
}
DocEntity::DocEntity(QTreeWidget *parent) :
    QTreeWidgetItem(parent), m_level(0), m_id(0), m_num(0)
{
    connect(this,SIGNAL(childWakedUp(DocEntity*)),dynamic_cast<TreeDoc*>(parent),SIGNAL(childWakeUp(DocEntity*)));
    connect(this,SIGNAL(removeItem(DocEntity*)),dynamic_cast<TreeDoc*>(treeWidget()),SLOT(removeItem(DocEntity*)));
    connect(this,SIGNAL(stateMessage(QString,int)),dynamic_cast<TreeDoc*>(treeWidget()),SIGNAL(state_message(QString,int)));
    connect(this,SIGNAL(changed()),dynamic_cast<TreeDoc*>(treeWidget()),SIGNAL(itemWasChanged()));
    connect(this,SIGNAL(newItem(DocEntity*)), dynamic_cast<TreeDoc*>(treeWidget()),SLOT(turnOnHighlight(DocEntity*)));
    connect(this,SIGNAL(changed()),this,SLOT(onChanged()));
    connect(this,SIGNAL(wasChanged(DocEntity*)),dynamic_cast<TreeDoc*>(treeWidget()),SLOT(onChangedItem(DocEntity*)));
    connect(this,SIGNAL(wasSaved(DocEntity*)),dynamic_cast<TreeDoc*>(treeWidget()),SLOT(onSavedItem(DocEntity*)));
    connect(this,SIGNAL(wasRefresh()),dynamic_cast<TreeDoc*>(treeWidget()),SIGNAL(wasRefreshItem()));
    setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
}

int DocEntity::level() const
{
    return m_level;
}
int DocEntity::id() const
{
    return m_id;
}

DocEntity::Operations* DocEntity::operations()
{
    return &m_operations;
}
int DocEntity::num() const
{
    return m_num;
}
QString DocEntity::capTemplate()
{
    return tr("%1");
}
void DocEntity::setID(const int &ID)
{
    m_id=ID;
}
void DocEntity::setNum(const int &Num)
{
    m_num=Num;
    setText(0,tr("%1 №%2").arg(capTemplate()).arg(Num));
}

DocEntity* DocEntity::parent() const
{
    return (QTreeWidgetItem::parent()!=0)?
                dynamic_cast<DocEntity*>(QTreeWidgetItem::parent()):0;
}
bool DocEntity::isChanged() const
{
    return font(0).italic();
}
void DocEntity::remove()
{
    if(m_id>0)
    {
        QMessageBox box(treeWidget());
        box.setText(tr("Вы действительно хотите удалить %1?").arg(text(0)));
        box.setIcon(QMessageBox::Question);
        box.setWindowTitle(tr("Удаление"));
        box.addButton(tr("Да"),QMessageBox::NoRole);
        QAbstractButton* no=box.addButton(tr("Нет"),QMessageBox::NoRole);
        box.exec();
        if(box.clickedButton()==no) return;

        emit stateMessage(tr("Идет удаление. Пожалуйста подождите..."),0);
        if(!checkCode())
        {
             emit stateMessage(tr("Удаление не выполнено."),5000);
             return;
        }
        if(!removeFromDB())
        {
            emit stateMessage(tr(""),0);
            return;
        }
        else
        {
            emit stateMessage(tr("Операция успешно завершена."),5000);
        }
    }
    if(parent()!=0)
    {
        for(int i=num();i<parent()->childCount();i++)
            dynamic_cast<DocEntity*>(parent()->child(i))->setNum(i);
    }
    else
        for(int i=num();i<treeWidget()->topLevelItemCount();i++)
            dynamic_cast<DocEntity*>(treeWidget()->topLevelItem(i))->setNum(i);
    emit removeItem(this);
}
bool DocEntity::checkCode()
{
    ConfirmDialog dialog(dynamic_cast<TreeDoc*>(treeWidget())->db());
    dialog.exec();
    return(dialog.result()==QDialog::Accepted);
}
void DocEntity::setState(const int &state)
{
    m_state=state;
}
void DocEntity::setColor(const QColor &color)
{
    QBrush brash = foreground(0);
    brash.setColor(color);
    setForeground(0,brash);
}
int DocEntity::state() const
{
    return m_state;
}
QString DocEntity::status() const
{
    return dynamic_cast<TreeDoc*>(treeWidget())->statusByState(m_state);
}
void DocEntity::save()
{
    if(isCorrect())
    {
        emit stateMessage(tr("Идет запись в базу. Пожалуйста подождите..."),0);
        if(!checkCode())
        {
             emit stateMessage(tr("Сохранение не выполнено."),5000);
             return;
        }
        if(!saveToDB())
        {
            QMessageBox::warning(treeWidget(),
                                         tr("Ошибка записи"),
                                         tr("Не удалось сохранить %1 №%2 в базу данных.").arg(capTemplate()).arg(m_num),
                                         QMessageBox::Ok);
            emit stateMessage(tr(""),0);
        }
        else
        {
            emit stateMessage(tr("Операция успешно завершена."),5000);
            refresh(Himself);
            emit wasSaved(this);
        }
    }
}
void DocEntity::onChanged()
{
    if(!isChanged()) emit wasChanged(this);
    setChanged(true);
}
void DocEntity::setChanged(const bool &arg)
{
    QFont curr = font(0);
    curr.setItalic(arg);
    setFont(0,curr);
}
bool DocEntity::isCompleted()
{
    if(childCount()==0) giveBithTo();
    for(int i=0;i<childCount();i++)
        if(dynamic_cast<DocEntity*>(child(i))->isCompleted()) return true;
    return false;
}
bool DocEntity::isDelinquent()
{
    if(childCount()==0) giveBithTo();
    for(int i=0;i<childCount();i++)
        if(dynamic_cast<DocEntity*>(child(i))->isDelinquent()) return true;
    return false;
}
bool DocEntity::isPerformed()
{
    if(childCount()==0) giveBithTo();
    for(int i=0;i<childCount();i++)
        if(dynamic_cast<DocEntity*>(child(i))->isPerformed()) return true;
    return false;
}
bool DocEntity::isEdited()
{
    if(childCount()==0) giveBithTo();
    for(int i=0;i<childCount();i++)
        if(dynamic_cast<DocEntity*>(child(i))->isEdited()) return true;
    return false;
}
void DocEntity::refresh()
{
    emit stateMessage(tr("Элемент обновляется. Пожалуйста подождите..."),40000);
    refresh(Himself);
    if(childCount()>0) refresh(Children);
    emit stateMessage(tr("Элемент обновлен."),5000);
}
